Skip to content

feat(pro): EPIC-PRO-17 seat hygiene client and CLI [STORY-17.1-17.5-17.6]#799

Merged
rafaelscosta merged 7 commits into
mainfrom
feature/pro-ux-error-bridge
Jul 13, 2026
Merged

feat(pro): EPIC-PRO-17 seat hygiene client and CLI [STORY-17.1-17.5-17.6]#799
rafaelscosta merged 7 commits into
mainfrom
feature/pro-ux-error-bridge

Conversation

@rafaelscosta

@rafaelscosta rafaelscosta commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the client half of EPIC-PRO-17 (Seat Hygiene & Machine ID Persistence):

  • Bumps @aiox-squads/pro submodule with persisted ~/.aiox/machine.id, machineIdSource telemetry, and legacy warning
  • Unifies machine-id barrel across install wizard (pro-setup), activate, and artifact broker
  • Adds aiox pro seats list|release self-service CLI
  • License tests: machine-id-store, license-crypto persisted source

Companion PRs

  • aiox-pro: feat/epic-pro-17-seat-hygiene → main
  • aios-license-server: feat/pro-15.2-grant-library → main
  • sinkra-hub: feat/epic-pro-17-seat-hygiene → rafaelscosta

Tests

  • npx jest tests/license/ — 323 passed

Deploy

Merge triggers semantic-release → @aiox-squads/core npm publish.

Summary by CodeRabbit

  • New Features
    • Added aiox pro seats list to view used/max seats and active seat activation details for the current machine.
    • Added aiox pro seats release <activationId> to release a seat from the current machine.
  • Improvements
    • Pro licensing/artifact requests now improve machine identification reliability, include persisted source tracking, and better surface structured server error details.
    • Strengthened Claude integration validation with allowlist-based checks, including symbolic links, for commands, skills, and agent memory.
  • Tests
    • Added/updated coverage for machine-id persistence/source, Pro request payloads, Claude validation behavior, and aiox pro seats help output (no plaintext password flag).

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
aiox-core Ready Ready Preview, Comment Jul 13, 2026 8:42pm

Request Review

@github-actions github-actions Bot added area: agents Agent system related type: test Test coverage and quality area: core Core framework (.aios-core/core/) area: installer Installer and setup (packages/installer/) area: cli CLI tools (bin/, packages/aios-pro-cli/) area: docs Documentation (docs/) labels Jul 8, 2026
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Changes

Adds authenticated Pro seat listing and release commands, propagates machine-ID provenance through installer licensing requests, improves structured error handling, and expands Claude integration namespace validation with allowlists and metrics.

Pro Seats CLI

Layer / File(s) Summary
Seats command implementation and wiring
.aiox-core/cli/commands/pro/seats.js, .aiox-core/cli/commands/pro/index.js, .aiox-core/install-manifest.yaml
Adds aiox pro seats list and release, authentication handling, license API calls, output formatting, command registration, and installation metadata.
Seats command tests
tests/cli/pro-seats.test.js
Covers help output, token forwarding, machine identity usage, and list/release API calls.

Installer Machine-ID Provenance

Layer / File(s) Summary
Machine-ID source and licensing request flow
packages/installer/src/wizard/pro-setup.js, pro
Parses nested license errors, adds machineIdSource and core-version fields to requests, and prefers the Pro machine-ID implementation.
Machine-ID persistence validation
tests/license/license-crypto.test.js, tests/license/machine-id-store.test.js, tests/installer/pro-setup-auth.test.js
Tests persisted machine IDs, provenance reporting, validation, permissions, corrupted data handling, and request payloads.

Claude Integration Governance

Layer / File(s) Summary
Claude allowlist validation logic
.aiox-core/infrastructure/scripts/validate-claude-integration.js, .aiox-core/install-manifest.yaml
Validates native agents and Claude top-level namespaces against allowlists and reports expanded metrics and errors.
Claude namespace enumeration validation
tests/unit/validate-claude-integration.test.js
Verifies symbolic-link entries are included in top-level Claude entry enumeration and filesystem mocks are restored.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SeatsCLI as aiox pro seats
  participant licenseApi
  User->>SeatsCLI: invoke list or release
  SeatsCLI->>SeatsCLI: resolve credentials and machine id
  SeatsCLI->>licenseApi: listSeats or releaseSeat
  licenseApi-->>SeatsCLI: return seat data or error
  SeatsCLI-->>User: print result
Loading
sequenceDiagram
  participant ProSetup as InlineLicenseClient
  participant MachineId as Pro machine-id module
  participant LicenseServer
  ProSetup->>MachineId: generate machine id and source
  MachineId-->>ProSetup: return machine id and provenance
  ProSetup->>LicenseServer: send licensing request with machineIdSource
  LicenseServer-->>ProSetup: return success or structured error envelope
Loading

Possibly related PRs

Suggested labels: area: cli, area: pro, area: health-check, area: core

Suggested reviewers: oalanicolas, pedrovaleriolopez

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main scope: Pro seat hygiene client work plus new CLI commands.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/pro-ux-error-bridge

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (13)
.aiox-core/cli/commands/pro/seats.js (1)

18-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate license-resolution logic with index.js.

resolveLicensePath and loadModules here re-implement the same candidate-path search and dynamic-require pattern already present in .aiox-core/cli/commands/pro/index.js (resolveLicensePath / loadLicenseModules). Any future change to path resolution or module list has to be kept in sync in two places.

Consider extracting a shared helper (e.g., pro/license-module-loader.js) exporting resolveLicensePath() and a generic loadProLicenseModules(names) used by both files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 18 - 56, `seats.js`
duplicates the same license path resolution and dynamic module loading logic
already implemented in `index.js`, so the two implementations can drift apart.
Refactor the shared path/module lookup into a common helper (for example, a
license loader utility) that exports `resolveLicensePath()` and a generic
`loadProLicenseModules(...)`, then have both `seats.js` and `index.js` call that
shared helper instead of maintaining separate `resolveLicensePath` and
`loadModules`/`loadLicenseModules` implementations.
.aiox-core/cli/commands/pro/index.js (1)

26-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Relative import used for createSeatsCommand.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should "Use absolute imports instead of relative imports in all code," but line 26 imports the new module via a relative path (./seats). If the project has an established absolute-import mechanism for this CLI package (e.g. package exports/path alias), please convert this to match; otherwise, please confirm how "absolute imports" should be applied in this CommonJS CLI context, since sibling-module relative requires are used elsewhere in this codebase.

As per coding guidelines, "Use absolute imports instead of relative imports in all code."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/index.js at line 26, The import for
createSeatsCommand in the pro CLI index uses a sibling relative require, which
conflicts with the absolute-import guideline. Update the pro command entrypoint
to use the project’s established absolute import mechanism for this CLI package,
or confirm and align with the codebase’s standard CommonJS approach if absolute
resolution is not available. Keep the change localized around createSeatsCommand
in the index module so it matches the rest of the package’s import style.

Source: Coding guidelines

packages/aiox-pro-cli/src/error-bridge.js (2)

8-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports instead of relative imports.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports. These cross-package require('../../../.aiox-core/...') paths are fragile and should use package-level imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/aiox-pro-cli/src/error-bridge.js` around lines 8 - 9, The imports in
error-bridge are using fragile relative paths instead of the required
package-level absolute imports. Update the require statements that load
AIOXError, defaultErrorRegistry, and proErrorRegistry so they resolve through
the package import name/path used elsewhere in the repo, keeping the same
symbols but removing the ../../../.aiox-core traversal.

Source: Coding guidelines


11-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import the shared default error code instead of hardcoding it
packages/aiox-pro-cli/src/error-bridge.js:11 should reuse DEFAULT_ERROR_CODE from the shared errors export surface so this value stays aligned with the canonical registry.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/aiox-pro-cli/src/error-bridge.js` at line 11, The default error code
is hardcoded in error-bridge instead of using the shared canonical value. Update
error-bridge.js to import DEFAULT_ERROR_CODE from the shared errors export
surface and use that symbol in place of the local DEFAULT_CODE constant, so the
bridge stays aligned with the central registry. Keep the change localized around
the error-bridge module and preserve any existing error mapping logic.
tests/pro-cli/error-bridge.test.js (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports instead of relative imports.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/pro-cli/error-bridge.test.js` at line 1, The test file currently
imports parseEnvelopeToAIOXError using a relative path, which violates the
absolute-import guideline for JS/TS files. Update the import in
error-bridge.test.js to use the project’s absolute alias/module path for
parseEnvelopeToAIOXError instead of
../../packages/aiox-pro-cli/src/error-bridge, keeping the same symbol name so
the test continues to reference the same function.

Source: Coding guidelines

.aiox-core/core/errors/pro-error-registry.js (1)

11-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports instead of relative imports.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports instead of relative imports. These require('./error-registry') and require('./constants') calls use relative paths. Consider using package-level imports if the project supports them (e.g., require('@aiox-core/core/errors/error-registry')).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/core/errors/pro-error-registry.js around lines 11 - 12, The
imports in pro-error-registry.js are using relative require paths, which
violates the absolute-import guideline. Update the top-level require statements
in the module that defines ErrorRegistry, ErrorCategory, and ErrorSeverity to
use the project’s package-level import aliases instead of './error-registry' and
'./constants', keeping the same exported symbols and module structure.

Source: Coding guidelines

tests/core/errors/pro-error-registry.test.js (1)

1-2: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports instead of relative imports.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports. Both require calls here use deep relative paths (../../../.aiox-core/...).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/core/errors/pro-error-registry.test.js` around lines 1 - 2, The test
file is using deep relative require paths, which violates the absolute-imports
guideline. Update the imports in the proErrorRegistry test to use the project’s
absolute module path for the `.aiox-core/core/errors/pro-error-registry` and
`.aiox-core/core/errors` modules, and keep the same exported symbols
(`proErrorRegistry`, `PRO_ERROR_DEFINITIONS`, `defaultErrorRegistry`,
`ErrorCategory`) so the test behavior stays unchanged.

Source: Coding guidelines

tests/pro-cli/render-error.test.js (1)

1-2: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports instead of relative imports.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/pro-cli/render-error.test.js` around lines 1 - 2, The test file is
using relative imports for parseEnvelopeToAIOXError and renderError/SUPPORT_URL,
but the codebase guideline requires absolute imports in JS/TS files. Update the
import statements in render-error.test.js to use the appropriate absolute
package/module paths that match the existing project import convention, keeping
the same symbols so the test continues to reference parseEnvelopeToAIOXError,
renderError, and SUPPORT_URL correctly.

Source: Coding guidelines

tests/pro-cli/recovery-actions.test.js (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports instead of relative imports.

As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/pro-cli/recovery-actions.test.js` at line 1, The test file is using a
relative require for recovery-actions, but the guideline requires absolute
imports in JS/TS files. Update the import in the recovery-actions test to use
the repository’s absolute module path, keeping the same symbols
getCacheCleanCommands and planRecoveryAction, and adjust any other similar
relative imports in this file if present.

Source: Coding guidelines

tests/license/license-crypto.test.js (1)

25-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports per coding guidelines.

The new require('../../pro/license/machine-id-store') uses a relative path. As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports instead of relative imports in all code.

♻️ Suggested fix
-const {
-  writePersistedMachineId,
-  _resetMachineIdStoreForTests,
-} = require('../../pro/license/machine-id-store');
+const {
+  writePersistedMachineId,
+  _resetMachineIdStoreForTests,
+} = require('`@aiox-squads/pro/license/machine-id-store`');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/license/license-crypto.test.js` around lines 25 - 28, The test file is
importing the license machine-id store with a relative path, which violates the
absolute import guideline. Update the require in the license-crypto test to use
the project’s absolute import path for machine-id-store, keeping the referenced
symbols writePersistedMachineId and _resetMachineIdStoreForTests unchanged.

Source: Coding guidelines

tests/license/machine-id-store.test.js (1)

7-17: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use absolute imports per coding guidelines.

Both import statements use relative paths (../../pro/license/...). As per coding guidelines, **/*.{js,jsx,ts,tsx} files should use absolute imports instead of relative imports in all code.

♻️ Suggested fix
-const {
-  readPersistedMachineId,
-  writePersistedMachineId,
-  isValidMachineId,
-  _resetMachineIdStoreForTests,
-  _PATHS,
-} = require('../../pro/license/machine-id-store');
-const {
-  generateMachineId,
-  _resetMachineIdCacheForTests,
-} = require('../../pro/license/license-crypto');
+const {
+  readPersistedMachineId,
+  writePersistedMachineId,
+  isValidMachineId,
+  _resetMachineIdStoreForTests,
+  _PATHS,
+} = require('`@aiox-squads/pro/license/machine-id-store`');
+const {
+  generateMachineId,
+  _resetMachineIdCacheForTests,
+} = require('`@aiox-squads/pro/license/license-crypto`');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/license/machine-id-store.test.js` around lines 7 - 17, The imports in
machine-id-store.test.js use relative paths, which violates the absolute-import
guideline for JS/TS files. Update the require statements that load
machine-id-store and license-crypto to use the project’s absolute import style
instead of ../../ paths, keeping the same exported symbols like
readPersistedMachineId, _resetMachineIdStoreForTests, generateMachineId, and
_resetMachineIdCacheForTests.

Source: Coding guidelines

tests/claude/subagent-governance.test.js (1)

10-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

expectedCoreNativeSubagents is missing 3 agents present in ALLOWED_NATIVE_SUBAGENTS.

The allowlist in validate-claude-integration.js permits 13 native subagents (aiox-master, aiox-squad-creator, aiox-ux-design-expert are the extras), but this test expects only 10 .md files. If any of those 3 agents are added to .claude/agents, the validator would pass but this governance test would fail. Consider adding a comment documenting the relationship between the two lists, or deriving the expected list from the allowlist to keep them in sync.

Also applies to: 46-46

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/claude/subagent-governance.test.js` around lines 10 - 21, The expected
native subagent list in the governance test is out of sync with the allowlist
used by validate-claude-integration.js. Update expectedCoreNativeSubagents in
the test to include the three additional native agents, or derive the expected
filenames from ALLOWED_NATIVE_SUBAGENTS so the two lists stay aligned. Use the
existing expectedCoreNativeSubagents constant and the validator’s allowlist as
the main symbols to locate the change.
.aiox-core/infrastructure/scripts/validate-claude-integration.js (1)

110-138: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Agent-memory validation uses a prefix check while other validations use explicit allowlists.

The native agent, command, and skill checks all use Set.has() for explicit membership testing, but the agent-memory check uses !entry.startsWith('aiox-'). This is more permissive — any directory starting with aiox- passes, even if it doesn't correspond to a real agent. Consider validating against the actual agent IDs or an explicit allowlist for consistency with the other checks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/infrastructure/scripts/validate-claude-integration.js around
lines 110 - 138, The agent-memory check in validate-claude-integration.js is
using a broad prefix rule instead of explicit membership like the native agent,
command, and skill checks. Update the agentMemoryEntries validation to use the
same allowlist pattern as ALLOWED_NATIVE_SUBAGENTS,
ALLOWED_CLAUDE_COMMAND_ENTRIES, and ALLOWED_CLAUDE_SKILL_ENTRIES, so only known
agent-memory namespaces are accepted. Keep the existing error reporting
structure, but base disallowedAgentMemoryEntries on the explicit allowed set
rather than startsWith('aiox-').
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.aiox-core/cli/commands/pro/seats.js:
- Around line 89-156: `generateMachineId()` is currently called outside the
error-handling path in both `listSeatsAction` and `releaseSeatAction`, so
failures can bypass the friendly CLI error messages. Move the
`generateMachineId()` call into the existing `try` blocks (or wrap the entire
action body) in those functions so any machine-id read/write error is caught and
reported consistently with the `licenseApi` failures. While touching
`releaseSeatAction`, add the missing `return` immediately after the usage
error/`process.exit(1)` guard for consistency with the rest of the command flow.
- Around line 161-167: The authOptions CLI parser currently exposes a plaintext
--password flag, which is a credential-risk issue. Update the auth flow in
authOptions (and any downstream consumers in seats.js) to prefer --token or
environment-based auth, deprecate or remove --password, and if it must remain
for compatibility, emit a clear warning when cmd.option('--password <password>')
is used directly so callers are steered to safer alternatives.
- Around line 58-82: Update resolveAccessToken to accept licenseApi as an
argument instead of calling loadModules internally, and adjust its callers to
pass the already-loaded licenseApi through. Remove the dead ternary in the catch
block by using the actual error message handling you want without the redundant
instanceof check, and add an explicit return immediately after the
authentication failure process.exit(1) path so execution cannot continue into
licenseApi.login with missing credentials.

---

Nitpick comments:
In @.aiox-core/cli/commands/pro/index.js:
- Line 26: The import for createSeatsCommand in the pro CLI index uses a sibling
relative require, which conflicts with the absolute-import guideline. Update the
pro command entrypoint to use the project’s established absolute import
mechanism for this CLI package, or confirm and align with the codebase’s
standard CommonJS approach if absolute resolution is not available. Keep the
change localized around createSeatsCommand in the index module so it matches the
rest of the package’s import style.

In @.aiox-core/cli/commands/pro/seats.js:
- Around line 18-56: `seats.js` duplicates the same license path resolution and
dynamic module loading logic already implemented in `index.js`, so the two
implementations can drift apart. Refactor the shared path/module lookup into a
common helper (for example, a license loader utility) that exports
`resolveLicensePath()` and a generic `loadProLicenseModules(...)`, then have
both `seats.js` and `index.js` call that shared helper instead of maintaining
separate `resolveLicensePath` and `loadModules`/`loadLicenseModules`
implementations.

In @.aiox-core/core/errors/pro-error-registry.js:
- Around line 11-12: The imports in pro-error-registry.js are using relative
require paths, which violates the absolute-import guideline. Update the
top-level require statements in the module that defines ErrorRegistry,
ErrorCategory, and ErrorSeverity to use the project’s package-level import
aliases instead of './error-registry' and './constants', keeping the same
exported symbols and module structure.

In @.aiox-core/infrastructure/scripts/validate-claude-integration.js:
- Around line 110-138: The agent-memory check in validate-claude-integration.js
is using a broad prefix rule instead of explicit membership like the native
agent, command, and skill checks. Update the agentMemoryEntries validation to
use the same allowlist pattern as ALLOWED_NATIVE_SUBAGENTS,
ALLOWED_CLAUDE_COMMAND_ENTRIES, and ALLOWED_CLAUDE_SKILL_ENTRIES, so only known
agent-memory namespaces are accepted. Keep the existing error reporting
structure, but base disallowedAgentMemoryEntries on the explicit allowed set
rather than startsWith('aiox-').

In `@packages/aiox-pro-cli/src/error-bridge.js`:
- Around line 8-9: The imports in error-bridge are using fragile relative paths
instead of the required package-level absolute imports. Update the require
statements that load AIOXError, defaultErrorRegistry, and proErrorRegistry so
they resolve through the package import name/path used elsewhere in the repo,
keeping the same symbols but removing the ../../../.aiox-core traversal.
- Line 11: The default error code is hardcoded in error-bridge instead of using
the shared canonical value. Update error-bridge.js to import DEFAULT_ERROR_CODE
from the shared errors export surface and use that symbol in place of the local
DEFAULT_CODE constant, so the bridge stays aligned with the central registry.
Keep the change localized around the error-bridge module and preserve any
existing error mapping logic.

In `@tests/claude/subagent-governance.test.js`:
- Around line 10-21: The expected native subagent list in the governance test is
out of sync with the allowlist used by validate-claude-integration.js. Update
expectedCoreNativeSubagents in the test to include the three additional native
agents, or derive the expected filenames from ALLOWED_NATIVE_SUBAGENTS so the
two lists stay aligned. Use the existing expectedCoreNativeSubagents constant
and the validator’s allowlist as the main symbols to locate the change.

In `@tests/core/errors/pro-error-registry.test.js`:
- Around line 1-2: The test file is using deep relative require paths, which
violates the absolute-imports guideline. Update the imports in the
proErrorRegistry test to use the project’s absolute module path for the
`.aiox-core/core/errors/pro-error-registry` and `.aiox-core/core/errors`
modules, and keep the same exported symbols (`proErrorRegistry`,
`PRO_ERROR_DEFINITIONS`, `defaultErrorRegistry`, `ErrorCategory`) so the test
behavior stays unchanged.

In `@tests/license/license-crypto.test.js`:
- Around line 25-28: The test file is importing the license machine-id store
with a relative path, which violates the absolute import guideline. Update the
require in the license-crypto test to use the project’s absolute import path for
machine-id-store, keeping the referenced symbols writePersistedMachineId and
_resetMachineIdStoreForTests unchanged.

In `@tests/license/machine-id-store.test.js`:
- Around line 7-17: The imports in machine-id-store.test.js use relative paths,
which violates the absolute-import guideline for JS/TS files. Update the require
statements that load machine-id-store and license-crypto to use the project’s
absolute import style instead of ../../ paths, keeping the same exported symbols
like readPersistedMachineId, _resetMachineIdStoreForTests, generateMachineId,
and _resetMachineIdCacheForTests.

In `@tests/pro-cli/error-bridge.test.js`:
- Line 1: The test file currently imports parseEnvelopeToAIOXError using a
relative path, which violates the absolute-import guideline for JS/TS files.
Update the import in error-bridge.test.js to use the project’s absolute
alias/module path for parseEnvelopeToAIOXError instead of
../../packages/aiox-pro-cli/src/error-bridge, keeping the same symbol name so
the test continues to reference the same function.

In `@tests/pro-cli/recovery-actions.test.js`:
- Line 1: The test file is using a relative require for recovery-actions, but
the guideline requires absolute imports in JS/TS files. Update the import in the
recovery-actions test to use the repository’s absolute module path, keeping the
same symbols getCacheCleanCommands and planRecoveryAction, and adjust any other
similar relative imports in this file if present.

In `@tests/pro-cli/render-error.test.js`:
- Around line 1-2: The test file is using relative imports for
parseEnvelopeToAIOXError and renderError/SUPPORT_URL, but the codebase guideline
requires absolute imports in JS/TS files. Update the import statements in
render-error.test.js to use the appropriate absolute package/module paths that
match the existing project import convention, keeping the same symbols so the
test continues to reference parseEnvelopeToAIOXError, renderError, and
SUPPORT_URL correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2502f52a-90af-438c-b1d1-db6d3e4b762b

📥 Commits

Reviewing files that changed from the base of the PR and between 77265d5 and d20dcb0.

📒 Files selected for processing (57)
  • .aiox-core/cli/commands/pro/index.js
  • .aiox-core/cli/commands/pro/seats.js
  • .aiox-core/core/errors/pro-error-registry.js
  • .aiox-core/data/entity-registry.yaml
  • .aiox-core/infrastructure/scripts/validate-claude-integration.js
  • .aiox-core/install-manifest.yaml
  • .claude/agent-memory/oalanicolas/MEMORY.md
  • .claude/agent-memory/pedro-valerio/MEMORY.md
  • .claude/agent-memory/sop-extractor/MEMORY.md
  • .claude/agent-memory/squad/MEMORY.md
  • .claude/agents/brad-frost.md
  • .claude/agents/copy-chief.md
  • .claude/agents/cyber-chief.md
  • .claude/agents/dan-mall.md
  • .claude/agents/data-chief.md
  • .claude/agents/dave-malouf.md
  • .claude/agents/db-sage.md
  • .claude/agents/design-chief.md
  • .claude/agents/design-system.md
  • .claude/agents/legal-chief.md
  • .claude/agents/nano-banana-generator.md
  • .claude/agents/oalanicolas.md
  • .claude/agents/pedro-valerio.md
  • .claude/agents/sop-extractor.md
  • .claude/agents/squad-chief.md
  • .claude/agents/squad.md
  • .claude/agents/story-chief.md
  • .claude/agents/tools-orchestrator.md
  • .claude/agents/traffic-masters-chief.md
  • .claude/commands/AIOX/scripts/agent-config-loader.js
  • .claude/commands/cohort-squad/agents/cohort-manager.md
  • .claude/commands/design-system/agents/brad-frost.md
  • .claude/commands/design-system/agents/dan-mall.md
  • .claude/commands/design-system/agents/dave-malouf.md
  • .claude/commands/design-system/agents/design-chief.md
  • .claude/commands/design-system/agents/nano-banana-generator.md
  • .claude/skills/clone-mind.md
  • .claude/skills/course-generation-workflow.md
  • .claude/skills/enhance-workflow.md
  • .claude/skills/ralph.md
  • .claude/skills/squad.md
  • .codex/skills/aiox-claude-mastery-chief/SKILL.md
  • eslint.config.js
  • packages/aiox-pro-cli/src/error-bridge.js
  • packages/aiox-pro-cli/src/recovery-actions.js
  • packages/aiox-pro-cli/src/render-error.js
  • packages/installer/src/wizard/pro-setup.js
  • pro
  • tests/claude/subagent-governance.test.js
  • tests/core/errors/pro-error-registry.test.js
  • tests/integration/codex-skills-sync.test.js
  • tests/license/license-crypto.test.js
  • tests/license/machine-id-store.test.js
  • tests/pro-cli/error-bridge.test.js
  • tests/pro-cli/recovery-actions.test.js
  • tests/pro-cli/render-error.test.js
  • tests/unit/validate-claude-integration.test.js
💤 Files with no reviewable changes (35)
  • .claude/agents/sop-extractor.md
  • .claude/skills/clone-mind.md
  • .claude/agents/pedro-valerio.md
  • .claude/skills/course-generation-workflow.md
  • .claude/agent-memory/oalanicolas/MEMORY.md
  • .claude/commands/cohort-squad/agents/cohort-manager.md
  • .claude/commands/design-system/agents/design-chief.md
  • .claude/agents/story-chief.md
  • .codex/skills/aiox-claude-mastery-chief/SKILL.md
  • .claude/agents/dave-malouf.md
  • .claude/agent-memory/sop-extractor/MEMORY.md
  • .claude/agent-memory/squad/MEMORY.md
  • .claude/agents/design-chief.md
  • .claude/skills/squad.md
  • .claude/agents/cyber-chief.md
  • .claude/commands/design-system/agents/nano-banana-generator.md
  • .claude/agents/squad.md
  • .claude/skills/ralph.md
  • .claude/agents/nano-banana-generator.md
  • .claude/commands/design-system/agents/dave-malouf.md
  • .claude/agents/dan-mall.md
  • .claude/skills/enhance-workflow.md
  • .claude/commands/design-system/agents/dan-mall.md
  • .claude/agents/db-sage.md
  • .claude/commands/design-system/agents/brad-frost.md
  • .claude/agents/design-system.md
  • .claude/agents/tools-orchestrator.md
  • .claude/agents/brad-frost.md
  • .claude/agent-memory/pedro-valerio/MEMORY.md
  • .claude/agents/copy-chief.md
  • .claude/agents/legal-chief.md
  • .claude/agents/traffic-masters-chief.md
  • .claude/agents/squad-chief.md
  • .claude/agents/oalanicolas.md
  • .claude/agents/data-chief.md

Comment thread .aiox-core/cli/commands/pro/seats.js Outdated
Comment thread .aiox-core/cli/commands/pro/seats.js
Comment thread .aiox-core/cli/commands/pro/seats.js
rafaelscosta and others added 3 commits July 13, 2026 16:15
…-17.5][STORY-17.6]

- Bump @aiox-squads/pro submodule with persisted machine id and telemetry
- Unify machine-id barrel across install wizard, activate, and artifact broker
- Add aiox pro seats list|release self-service commands and license tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rafaelscosta
rafaelscosta force-pushed the feature/pro-ux-error-bridge branch from d20dcb0 to 299d730 Compare July 13, 2026 19:57
@github-actions github-actions Bot removed area: agents Agent system related area: core Core framework (.aios-core/core/) area: cli CLI tools (bin/, packages/aios-pro-cli/) labels Jul 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage Report

Coverage report not available

📈 Full coverage report available in Codecov


Generated by PR Automation (Story 6.1)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
.aiox-core/cli/commands/pro/seats.js (3)

161-167: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Plaintext --password flag still unguarded — still present.

--password remains accepted as a CLI flag without any warning about shell-history/process-list exposure, same as previously flagged.

As per path instructions, "Look for potential security vulnerabilities."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 161 - 167, Update
authOptions to remove the plaintext --password CLI option, leaving only the
supported safer authentication options such as --email and --token. Ensure
command parsing no longer accepts or exposes passwords through this flag.

Source: Path instructions


89-156: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

generateMachineId() still uncaught; missing return after usage-error exit — still present.

generateMachineId() at lines 92 and 140 remains outside the try blocks in listSeatsAction/releaseSeatAction, so a persistence failure surfaces as a raw stack trace instead of the friendly error path. releaseSeatAction's process.exit(1) at line 136 still isn't followed by return.

As per path instructions, "Verify error handling is comprehensive."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 89 - 156, Wrap
generateMachineId() within the existing try/catch flows of listSeatsAction and
releaseSeatAction so persistence failures use the friendly error handling. In
releaseSeatAction, return immediately after the usage-error process.exit(1)
before resolving credentials or generating the machine ID.

Source: Path instructions


58-82: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Dead ternary, redundant module reload, missing return after process.exit — still present.

Same three issues from the earlier review round remain: the instanceof AuthError ternary at line 78 always resolves to error.message; loadModules() is re-invoked here solely for licenseApi although every caller already has it; process.exit(1) at line 71 lacks a following return.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 58 - 82, Update
resolveAccessToken to accept and reuse the caller-provided licenseApi instead of
re-invoking loadModules(), remove the redundant AuthError-based ternary and use
error.message directly, and add an explicit return immediately after the
missing-credentials process.exit(1) path.
🧹 Nitpick comments (1)
.aiox-core/cli/commands/pro/index.js (1)

26-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Relative import conflicts with absolute-import guideline.

require('./seats') is a relative import; the coding guideline requires absolute imports for JS files. Confirm whether this codebase has an established absolute-import/alias mechanism to apply here consistently.

As per coding guidelines, "Use absolute imports."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/index.js at line 26, Update the import near
createSeatsCommand to use the repository’s established absolute-import or alias
mechanism instead of the relative './seats' path. Confirm the alias convention
from neighboring imports or project configuration and preserve the existing
createSeatsCommand usage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.aiox-core/cli/commands/pro/seats.js:
- Around line 84-121: Standardize listSeatsAction output to English: replace the
Portuguese machine marker and seat detail labels with English equivalents, and
update formatDate to use the locale convention used by the surrounding English
CLI output instead of hardcoding pt-BR. Keep the existing seat listing structure
and formatting behavior unchanged.

In @.aiox-core/infrastructure/scripts/validate-claude-integration.js:
- Around line 86-98: Update listTopLevelNames to include symlinked top-level
entries in its candidate set, resolving or explicitly recognizing Dirent
symlinks before the isGitIgnored allowlist check. Preserve the existing
projectRoot-relative filtering, name mapping, and sorting so disallowed symlink
namespaces remain visible to the governance validation and metrics.

---

Duplicate comments:
In @.aiox-core/cli/commands/pro/seats.js:
- Around line 161-167: Update authOptions to remove the plaintext --password CLI
option, leaving only the supported safer authentication options such as --email
and --token. Ensure command parsing no longer accepts or exposes passwords
through this flag.
- Around line 89-156: Wrap generateMachineId() within the existing try/catch
flows of listSeatsAction and releaseSeatAction so persistence failures use the
friendly error handling. In releaseSeatAction, return immediately after the
usage-error process.exit(1) before resolving credentials or generating the
machine ID.
- Around line 58-82: Update resolveAccessToken to accept and reuse the
caller-provided licenseApi instead of re-invoking loadModules(), remove the
redundant AuthError-based ternary and use error.message directly, and add an
explicit return immediately after the missing-credentials process.exit(1) path.

---

Nitpick comments:
In @.aiox-core/cli/commands/pro/index.js:
- Line 26: Update the import near createSeatsCommand to use the repository’s
established absolute-import or alias mechanism instead of the relative './seats'
path. Confirm the alias convention from neighboring imports or project
configuration and preserve the existing createSeatsCommand usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2bca5d0b-b1d8-4ed1-8125-0f5411505e0d

📥 Commits

Reviewing files that changed from the base of the PR and between d20dcb0 and 299d730.

📒 Files selected for processing (9)
  • .aiox-core/cli/commands/pro/index.js
  • .aiox-core/cli/commands/pro/seats.js
  • .aiox-core/infrastructure/scripts/validate-claude-integration.js
  • .aiox-core/install-manifest.yaml
  • packages/installer/src/wizard/pro-setup.js
  • pro
  • tests/installer/pro-setup-auth.test.js
  • tests/license/license-crypto.test.js
  • tests/license/machine-id-store.test.js
💤 Files with no reviewable changes (1)
  • pro
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/license/license-crypto.test.js
  • packages/installer/src/wizard/pro-setup.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

♻️ Duplicate comments (3)
.aiox-core/cli/commands/pro/seats.js (3)

161-167: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Plaintext --password flag still unguarded — still present.

--password remains accepted as a CLI flag without any warning about shell-history/process-list exposure, same as previously flagged.

As per path instructions, "Look for potential security vulnerabilities."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 161 - 167, Update
authOptions to remove the plaintext --password CLI option, leaving only the
supported safer authentication options such as --email and --token. Ensure
command parsing no longer accepts or exposes passwords through this flag.

Source: Path instructions


89-156: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

generateMachineId() still uncaught; missing return after usage-error exit — still present.

generateMachineId() at lines 92 and 140 remains outside the try blocks in listSeatsAction/releaseSeatAction, so a persistence failure surfaces as a raw stack trace instead of the friendly error path. releaseSeatAction's process.exit(1) at line 136 still isn't followed by return.

As per path instructions, "Verify error handling is comprehensive."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 89 - 156, Wrap
generateMachineId() within the existing try/catch flows of listSeatsAction and
releaseSeatAction so persistence failures use the friendly error handling. In
releaseSeatAction, return immediately after the usage-error process.exit(1)
before resolving credentials or generating the machine ID.

Source: Path instructions


58-82: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Dead ternary, redundant module reload, missing return after process.exit — still present.

Same three issues from the earlier review round remain: the instanceof AuthError ternary at line 78 always resolves to error.message; loadModules() is re-invoked here solely for licenseApi although every caller already has it; process.exit(1) at line 71 lacks a following return.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 58 - 82, Update
resolveAccessToken to accept and reuse the caller-provided licenseApi instead of
re-invoking loadModules(), remove the redundant AuthError-based ternary and use
error.message directly, and add an explicit return immediately after the
missing-credentials process.exit(1) path.
🧹 Nitpick comments (1)
.aiox-core/cli/commands/pro/index.js (1)

26-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Relative import conflicts with absolute-import guideline.

require('./seats') is a relative import; the coding guideline requires absolute imports for JS files. Confirm whether this codebase has an established absolute-import/alias mechanism to apply here consistently.

As per coding guidelines, "Use absolute imports."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/index.js at line 26, Update the import near
createSeatsCommand to use the repository’s established absolute-import or alias
mechanism instead of the relative './seats' path. Confirm the alias convention
from neighboring imports or project configuration and preserve the existing
createSeatsCommand usage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.aiox-core/cli/commands/pro/seats.js:
- Around line 84-121: Standardize listSeatsAction output to English: replace the
Portuguese machine marker and seat detail labels with English equivalents, and
update formatDate to use the locale convention used by the surrounding English
CLI output instead of hardcoding pt-BR. Keep the existing seat listing structure
and formatting behavior unchanged.

In @.aiox-core/infrastructure/scripts/validate-claude-integration.js:
- Around line 86-98: Update listTopLevelNames to include symlinked top-level
entries in its candidate set, resolving or explicitly recognizing Dirent
symlinks before the isGitIgnored allowlist check. Preserve the existing
projectRoot-relative filtering, name mapping, and sorting so disallowed symlink
namespaces remain visible to the governance validation and metrics.

---

Duplicate comments:
In @.aiox-core/cli/commands/pro/seats.js:
- Around line 161-167: Update authOptions to remove the plaintext --password CLI
option, leaving only the supported safer authentication options such as --email
and --token. Ensure command parsing no longer accepts or exposes passwords
through this flag.
- Around line 89-156: Wrap generateMachineId() within the existing try/catch
flows of listSeatsAction and releaseSeatAction so persistence failures use the
friendly error handling. In releaseSeatAction, return immediately after the
usage-error process.exit(1) before resolving credentials or generating the
machine ID.
- Around line 58-82: Update resolveAccessToken to accept and reuse the
caller-provided licenseApi instead of re-invoking loadModules(), remove the
redundant AuthError-based ternary and use error.message directly, and add an
explicit return immediately after the missing-credentials process.exit(1) path.

---

Nitpick comments:
In @.aiox-core/cli/commands/pro/index.js:
- Line 26: Update the import near createSeatsCommand to use the repository’s
established absolute-import or alias mechanism instead of the relative './seats'
path. Confirm the alias convention from neighboring imports or project
configuration and preserve the existing createSeatsCommand usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2bca5d0b-b1d8-4ed1-8125-0f5411505e0d

📥 Commits

Reviewing files that changed from the base of the PR and between d20dcb0 and 299d730.

📒 Files selected for processing (9)
  • .aiox-core/cli/commands/pro/index.js
  • .aiox-core/cli/commands/pro/seats.js
  • .aiox-core/infrastructure/scripts/validate-claude-integration.js
  • .aiox-core/install-manifest.yaml
  • packages/installer/src/wizard/pro-setup.js
  • pro
  • tests/installer/pro-setup-auth.test.js
  • tests/license/license-crypto.test.js
  • tests/license/machine-id-store.test.js
💤 Files with no reviewable changes (1)
  • pro
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/license/license-crypto.test.js
  • packages/installer/src/wizard/pro-setup.js
🛑 Comments failed to post (2)
.aiox-core/cli/commands/pro/seats.js (1)

84-121: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Inconsistent language in seat output — Portuguese labels mixed into English CLI text.

formatDate hardcodes toLocaleString('pt-BR'), and the seat detail lines use Portuguese labels ("esta máquina", "Nome:", "Versão:", "Ativado:", "Validado:") while the surrounding output ("AIOX Pro — Seats", "Used:", "Available:", all error strings) is English. This reads as an unintentional partial localization and will confuse most users of this command.

🌐 Suggested fix
-      const current = seat.isCurrentMachine ? ' (esta máquina)' : '';
+      const current = seat.isCurrentMachine ? ' (this machine)' : '';
       console.log(`  • ${seat.machineIdMasked}${current}`);
       console.log(`    ID:        ${seat.id}`);
       if (seat.machineName) {
-        console.log(`    Nome:      ${seat.machineName}`);
+        console.log(`    Name:      ${seat.machineName}`);
       }
       if (seat.aiosVersion) {
-        console.log(`    Versão:    ${seat.aiosVersion}`);
+        console.log(`    Version:   ${seat.aiosVersion}`);
       }
-      console.log(`    Ativado:   ${formatDate(seat.activatedAt)}`);
-      console.log(`    Validado:  ${formatDate(seat.lastValidatedAt)}`);
+      console.log(`    Activated: ${formatDate(seat.activatedAt)}`);
+      console.log(`    Validated: ${formatDate(seat.lastValidatedAt)}`);
 function formatDate(dateStr) {
   if (!dateStr) return '—';
-  return new Date(dateStr).toLocaleString('pt-BR');
+  return new Date(dateStr).toLocaleString();
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

function formatDate(dateStr) {
  if (!dateStr) return '—';
  return new Date(dateStr).toLocaleString();
}

async function listSeatsAction(options) {
  const { licenseApi, generateMachineId, AuthError } = loadModules();
  const accessToken = await resolveAccessToken(options, AuthError);
  const machineId = generateMachineId();

  try {
    const result = await licenseApi.listSeats(accessToken, machineId);

    console.log('\nAIOX Pro — Seats\n');
    console.log(`  Used:      ${result.summary.used}/${result.summary.max}`);
    console.log(`  Available: ${result.summary.available}`);
    console.log('');

    if (!result.seats || result.seats.length === 0) {
      console.log('  No active seats.');
      console.log('');
      return;
    }

    for (const seat of result.seats) {
      const current = seat.isCurrentMachine ? ' (this machine)' : '';
      console.log(`  • ${seat.machineIdMasked}${current}`);
      console.log(`    ID:        ${seat.id}`);
      if (seat.machineName) {
        console.log(`    Name:      ${seat.machineName}`);
      }
      if (seat.aiosVersion) {
        console.log(`    Version:   ${seat.aiosVersion}`);
      }
      console.log(`    Activated: ${formatDate(seat.activatedAt)}`);
      console.log(`    Validated: ${formatDate(seat.lastValidatedAt)}`);
      console.log('');
    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/cli/commands/pro/seats.js around lines 84 - 121, Standardize
listSeatsAction output to English: replace the Portuguese machine marker and
seat detail labels with English equivalents, and update formatDate to use the
locale convention used by the surrounding English CLI output instead of
hardcoding pt-BR. Keep the existing seat listing structure and formatting
behavior unchanged.
.aiox-core/infrastructure/scripts/validate-claude-integration.js (1)

86-98: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Symlinked top-level entries silently bypass the allowlist check.

entry.isDirectory() || entry.isFile() (line 89) excludes symlinks, since fs.Dirent reports both as false for a symlink unless resolved. A disallowed namespace added as a symlink under .claude/commands, .claude/skills, or .claude/agent-memory would be silently dropped from commandEntries/skillEntries/agentMemoryEntries — never flagged as disallowed and never counted in metrics, defeating the point of this governance check.

🔧 Suggested fix
   return fs.readdirSync(dirPath, { withFileTypes: true })
-    .filter((entry) => entry.isDirectory() || entry.isFile())
+    .filter((entry) => entry.isDirectory() || entry.isFile() || entry.isSymbolicLink())
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

function listTopLevelNames(dirPath, projectRoot) {
  if (!fs.existsSync(dirPath)) return [];
  return fs.readdirSync(dirPath, { withFileTypes: true })
    .filter((entry) => entry.isDirectory() || entry.isFile() || entry.isSymbolicLink())
    .filter((entry) => {
      if (!projectRoot) return true;
      const relativePath = path.relative(projectRoot, path.join(dirPath, entry.name)).split(path.sep).join('/');
      return !isGitIgnored(projectRoot, relativePath);
    })
  
    .map((entry) => entry.name)
    .sort();
}
🧰 Tools
🪛 ast-grep (0.44.1)

[error] 91-91: An archive entry path (e.g. entry.path / entry.fileName / header.name) is joined to an output directory without validating that the resolved path stays inside that directory. A malicious archive can use "../" sequences to escape the extraction directory and overwrite arbitrary files (Zip Slip). Resolve the path and verify it starts with the normalized output directory, or strip traversal with path.basename, before writing the entry.
Context: path.join(dirPath, entry.name)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(zip-slip-archive-extraction-javascript)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.aiox-core/infrastructure/scripts/validate-claude-integration.js around
lines 86 - 98, Update listTopLevelNames to include symlinked top-level entries
in its candidate set, resolving or explicitly recognizing Dirent symlinks before
the isGitIgnored allowlist check. Preserve the existing projectRoot-relative
filtering, name mapping, and sorting so disallowed symlink namespaces remain
visible to the governance validation and metrics.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/cli/pro-seats.test.js (1)

5-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider expanding test coverage beyond help output.

The test only verifies --password absence in help text. Adding tests for listSeatsAction and releaseSeatAction (e.g., mocking loadModules, resolveAccessToken, and licenseApi calls) would catch regressions in the core command logic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli/pro-seats.test.js` around lines 5 - 16, Expand the aiox pro seats
CLI tests beyond help output by adding coverage for listSeatsAction and
releaseSeatAction. Mock loadModules, resolveAccessToken, and the relevant
licenseApi calls, then verify both actions invoke the expected dependencies and
handle their results correctly.
tests/unit/validate-claude-integration.test.js (1)

85-100: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider moving mock restoration to afterEach for robustness.

jest.restoreAllMocks() at line 98 runs inside the test body. If the expect at line 96 fails, mocks are not restored and may leak into subsequent tests. Moving restoration to an afterEach hook ensures cleanup regardless of assertion outcomes.

♻️ Suggested refactor
   it('includes symbolic links when inspecting top-level Claude entries', () => {
     jest.spyOn(fs, 'existsSync').mockReturnValue(true);
     jest.spyOn(fs, 'readdirSync').mockReturnValue([
       {
         name: 'linked-skill',
         isDirectory: () => false,
         isFile: () => false,
         isSymbolicLink: () => true,
       },
     ]);

     expect(listTopLevelNames('/tmp/.claude/skills', null)).toEqual(['linked-skill']);
-
-    jest.restoreAllMocks();
   });
+
+  afterEach(() => {
+    jest.restoreAllMocks();
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/validate-claude-integration.test.js` around lines 85 - 100, Move
Jest mock cleanup from the symbolic-link test body into an afterEach hook for
the test suite, ensuring jest.restoreAllMocks() runs even when an assertion
fails; remove the inline restoration from the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/cli/pro-seats.test.js`:
- Line 3: Replace the relative require in the pro-seats test with the project’s
configured absolute import alias for the createSeatsCommand module. Verify the
Jest or package alias configuration and use the established `@aiox-core-style`
mapping without changing the command usage.

---

Nitpick comments:
In `@tests/cli/pro-seats.test.js`:
- Around line 5-16: Expand the aiox pro seats CLI tests beyond help output by
adding coverage for listSeatsAction and releaseSeatAction. Mock loadModules,
resolveAccessToken, and the relevant licenseApi calls, then verify both actions
invoke the expected dependencies and handle their results correctly.

In `@tests/unit/validate-claude-integration.test.js`:
- Around line 85-100: Move Jest mock cleanup from the symbolic-link test body
into an afterEach hook for the test suite, ensuring jest.restoreAllMocks() runs
even when an assertion fails; remove the inline restoration from the test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0b546180-5bf4-420e-b20c-ff7202c3a97c

📥 Commits

Reviewing files that changed from the base of the PR and between d1404d0 and f8659ae.

📒 Files selected for processing (5)
  • .aiox-core/cli/commands/pro/seats.js
  • .aiox-core/infrastructure/scripts/validate-claude-integration.js
  • .aiox-core/install-manifest.yaml
  • tests/cli/pro-seats.test.js
  • tests/unit/validate-claude-integration.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • .aiox-core/install-manifest.yaml
  • .aiox-core/infrastructure/scripts/validate-claude-integration.js

Comment thread tests/cli/pro-seats.test.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/cli/pro-seats.test.js (1)

50-82: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add error path test coverage for list and release actions.

Both tests only verify the happy path. The source code handles generateMachineId failure, missing authentication, and API rejections (all with process.exit(1)), but none of these paths are exercised. Adding a few error case tests would increase confidence in the error handling logic.

♻️ Suggested error path tests
   it('lists active seats using the authenticated machine identity', async () => {
     // ... existing test ...
   });

+  it('exits when generateMachineId fails', async () => {
+    mockGenerateMachineId.mockReset().mockImplementation(() => {
+      throw new Error('disk error');
+    });
+    jest.spyOn(console, 'error').mockImplementation(() => {});
+    const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {});
+
+    const command = createSeatsCommand();
+    const list = command.commands.find((c) => c.name() === 'list');
+    await list.parseAsync(['--token', 'access-token'], { from: 'user' });
+
+    expect(exitSpy).toHaveBeenCalledWith(1);
+    expect(mockLicenseApi.listSeats).not.toHaveBeenCalled();
+  });
+
+  it('exits when listSeats rejects', async () => {
+    mockLicenseApi.listSeats.mockRejectedValue(new Error('network error'));
+    jest.spyOn(console, 'error').mockImplementation(() => {});
+    const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {});
+
+    const command = createSeatsCommand();
+    const list = command.commands.find((c) => c.name() === 'list');
+    await list.parseAsync(['--token', 'access-token'], { from: 'user' });
+
+    expect(exitSpy).toHaveBeenCalledWith(1);
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli/pro-seats.test.js` around lines 50 - 82, Add error-path tests
alongside the existing `list` and `release` command tests, covering
`generateMachineId` failures, missing authentication, and
`listSeats`/`releaseSeat` API rejections. Mock `process.exit` and assert each
failure invokes it with status 1, while verifying the corresponding API is not
called when authentication or machine-ID generation fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/cli/pro-seats.test.js`:
- Around line 50-82: Add error-path tests alongside the existing `list` and
`release` command tests, covering `generateMachineId` failures, missing
authentication, and `listSeats`/`releaseSeat` API rejections. Mock
`process.exit` and assert each failure invokes it with status 1, while verifying
the corresponding API is not called when authentication or machine-ID generation
fails.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 539dd4a3-db7a-40d4-8603-61c409f35044

📥 Commits

Reviewing files that changed from the base of the PR and between f8659ae and f19fb96.

📒 Files selected for processing (2)
  • tests/cli/pro-seats.test.js
  • tests/unit/validate-claude-integration.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/validate-claude-integration.test.js

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 13, 2026
@rafaelscosta
rafaelscosta merged commit 0b32b68 into main Jul 13, 2026
51 checks passed
@rafaelscosta
rafaelscosta deleted the feature/pro-ux-error-bridge branch July 13, 2026 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs Documentation (docs/) area: installer Installer and setup (packages/installer/) type: test Test coverage and quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant